#include "plcconnecter.h"
#include "modbus/modbustcp.h"
#include <exception>
#include <string>
#include <log/log.h>
#include <QDebug>

namespace HIM {

PlcConnecter::PlcConnecter():
    plcCon(new ModbusTCP)
{

};

PlcConnecter::~PlcConnecter()
{  
    delete plcCon;
};

bool PlcConnecter::startConnect(string ip,uint16_t port,int slave_id)
{
    try
    {
        plcCon->setupMobus(ip,port,slave_id);
        plcCon->connect();
    }
    catch(std::exception & e)
    {
        HIM_ERROR("PLC connect error {}", e.what());
    }

    bool plcIsConnected = getConnectStatus();
    return plcIsConnected;
}

bool PlcConnecter::stopConnect()
{    
    try
    {
        plcCon->close();
    }
    catch (std::exception & e)
    {
        HIM_ERROR("PLC stopConnect error {}", e.what());
    }

    bool plcIsConnected = getConnectStatus();

    if(plcIsConnected)
        return false;
    else
        return true;
}

bool PlcConnecter::reConnect(string ip,uint16_t port,int slave_id)
{
    if(plcConnectStatus)
        stopConnect();

    startConnect(ip,port,slave_id);
    bool plcIsConnected = getConnectStatus();
    return plcIsConnected;
}

bool PlcConnecter::getConnectStatus()
{   
    bool plcStatus = plcCon->getConnected();

    if(plcConnectStatus!=plcStatus){
        plcConnectStatus = plcStatus;
    }
    return plcConnectStatus;
};

bool PlcConnecter::writeRegisters(int addr, int nb, uint16_t *dest)
{
    bool res=true;
    try
    {
        res=plcCon->write_holding_registers(addr,nb,dest);
    }
    catch (std::exception& e)
    {
        HIM_ERROR("PLC writeRegisters error : {}", e.what());
    }
    return res;
}

bool PlcConnecter::readRegisters(int addr, int nb, uint16_t *dest)
{
    bool res=true;
    try
    {
        res=plcCon->read_holding_registers(addr,nb,dest);
    }
    catch (std::exception& e)
    {
        HIM_ERROR("PLC readRegisters error : {}", e.what());
    }
    return res;
}

float PlcConnecter::getFloatFromDDByte(uint16_t *dest)
{
    return  modbus_get_float_abcd(dest);
}

void PlcConnecter::setFloatFromDDByte(float src,uint16_t *dest)
{
    modbus_set_float_abcd(src,dest);
}
}
